﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Data;

namespace Soket_MMTNC_Server
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            me = this;
            login lg = new login();
            lg.ShowInTaskbar = false;
            lg.ShowDialog();            
        }

        private void MenuItem_Click(object sender, RoutedEventArgs e)
        {
            Products pro = new Products();
            pro.ShowInTaskbar = false;
            pro.ShowDialog();
        }

        private void mnexit_click(object sender, RoutedEventArgs e)
        {
            System.Environment.Exit(0);
        }
        
        public void Run()
        {
            process = new Thread(Listen);
            process.Start();
            tb_stt.ScrollToEnd();
        }
        

        private void MenuItem_Click_4(object sender, RoutedEventArgs e)
        {
            Statistics st = new Statistics();
            st.ShowInTaskbar = false;
            st.ShowDialog();
        }

        public static MainWindow me;
        Thread process;
        //string kq = myIP.GetIP().ToString();
        // tạo ipendpoint với tham số là địa chỉ server và port của server. client sẽ dựa vô 2 tham số này mà tạo kết nối tới server
        IPEndPoint ipe = new IPEndPoint(myIP.GetIP(), 9999);
        // khai báo socket
        public static Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
        // tạo 1 list cái socket là các socket của các client sẽ kến nối đến ta đưa nó vào 1 danh sách.
        public static List<Socket> listclient = new List<Socket>();
        Product p = new Product();
        myIP myip = new myIP();
        //socket client
        public static Socket Clientsk;
        Thread clientprocess;
        User u=new User();
        void Listen()
        {
            server.Bind(ipe);
            // trong 1 lúc có thể xử lý 10 kết nối
            server.Listen(10);
            //doi lay thong tin chung thuc tu lient
            while (true)
            {
                Clientsk= server.Accept();
                //lay thong tin chung thuc tu lient               
                string username="";
                string password="";
               
                byte[] buff = new byte[1024];
                Clientsk.Receive(buff);
                // trước khi nhận thông tin phải giải mã từ byte sang object rồi mới sử dụng được
                    
                string ct = (string)myip.HamGiaiMa(buff);
                int vt = 0;
                foreach (var item in ct)
                {
                    if (item.Equals(' '))
                    {                            
                        break;
                    }
                    vt++;
                }
                username = ct.Substring(0, vt);
                password = ct.Substring(vt+1,ct.Length-(vt+1));

                
                
                if (u.Login(username, password))
                {
                    //gui thon tin dong y ket noi                    
                    Clientsk.Send(myip.MaHoa(1));
                    listclient.Add(Clientsk);
                    // dùng delegate và lambda expresstion mới có thể thao tác trên các control
                    tb_stt.Dispatcher.BeginInvoke((Action)(() => { tb_stt.AppendText("Chấp nhận kết nối từ " + Clientsk.RemoteEndPoint.ToString() + "\n"); }));
                    // tạo thread để luôn nhận thông tin từ client gửi đến
                    clientprocess = new Thread(ReceiveFromClent);
                    clientprocess.Start(Clientsk);
                    //truyen du lieu cho client
                    DataTable dt = p.GetDaTaForClient();
                    Clientsk.Send(myip.MaHoa(dt));
                }
                else
                {
                    //gui thon tin tu choi ket noi
                    Clientsk.Send(myip.MaHoa(0));
                }
            }
        }
        
        private void ReceiveFromClent(object obj)
        {
            try
            {
                Clientsk = (Socket)obj;
                while (true)
                {
                    byte[] buff = new byte[1024 * 5000];
                    Clientsk.Receive(buff);
                    // trước khi nhận thông tin phải giải mã từ byte sang object rồi mới sử dụng được 

                    DataTable dt = (DataTable)myip.HamGiaiMa(buff);
                    for (int i = 0; i < dt.Rows.Count; i++)
                    {
                        p.AddBill(int.Parse(dt.Rows[i]["id"].ToString()), 
                                            dt.Rows[i]["quantity"].ToString(), 
                                            dt.Rows[i]["date"].ToString());
                    }
                    
                }
            }
            catch (Exception ex)
            {
                foreach (var item in listclient)
                {
                    if (item.Connected == false)
                    {
                        if (MessageBox.Show("Client " + item.RemoteEndPoint.ToString() + " đã ngắt kết nối với máy chủ\n(" + ex.Message + ")", "Thông báo", MessageBoxButton.OK, MessageBoxImage.Warning) == MessageBoxResult.OK)
                        {
                            string client_name = item.RemoteEndPoint.ToString();
                            tb_stt.Dispatcher.BeginInvoke((Action)(() => { tb_stt.AppendText("Hủy kết nối giữa máy chủ và " + client_name + "\n"); }));
                            item.Close();
                            listclient.Remove(item);
                            break;
                        }
                    }
                }
              
            }
        }
       
    }
}
